package demo.concurrent.executors.forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * 　　　　　　　   ┏┓　   ┏┓+ +
 * 　　　　　　　┏┛┻━━━┛┻┓ + +
 * 　　　　　　　┃　　　　　　　┃
 * 　　　　　　　┃　　　━　　　┃ ++ + + +
 * 　　　　　　 ████━████ ┃+
 * 　　　　　　　┃　　　　　　　┃ +
 * 　　　　　　　┃　　　┻　　　┃
 * 　　　　　　　┃　　　　　　　┃ + +
 * 　　　　　　　┗━┓　　　┏━┛
 * 　　　　　　　　　┃　　　┃
 * 　　　　　　　　　┃　　　┃ + + + +
 * 　　　　　　　　　┃　　　┃			God beast body, code no BUG
 * 　　　　　　　　　┃　　　┃ +			神兽护体,代码无BUG
 * 　　　　　　　　　┃　　　┃
 * 　　　　　　　　　┃　　　┃　　+
 * 　　　　　　　　　┃　 　　┗━━━┓ + +
 * 　　　　　　　　　┃ 　　　　　　　┣┓
 * 　　　　　　　　　┃ 　　　　　　　┏┛
 * 　　　　　　　　　┗┓┓┏━┳┓┏┛ + + + +
 * 　　　　　　　　　　┃┫┫　┃┫┫
 * 　　　　　　　　　　┗┻┛　┗┻┛+ + + +
 *
 * @title: fork/join 测试
 * @author zhonghaijun
 * @date 2021-03-25
 */
public class TestForkJoinPool {

    private static final Integer MAX = 10000;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        TestForkJoinTask forkJoinTask = new TestForkJoinTask(1, 100000);
        ForkJoinTask<Integer> joinTask = forkJoinPool.submit(forkJoinTask);
        System.out.println(joinTask.get());

    }


    static class TestForkJoinTask extends RecursiveTask<Integer> {

        private Integer start;

        private Integer end;

        public TestForkJoinTask(Integer start, Integer end) {
            this.start = start;
            this.end = end;
        }

        @Override
        protected Integer compute() {
            if(end - start < MAX){
                Integer total = 0;
                System.out.println("开始计算的数据：start："+start + " end："+end);
                for (Integer i = this.start; i < end; i++) {
                    total += i;
                }
                return total;
            }else {
                TestForkJoinTask forkJoinTask1 = new TestForkJoinTask(start, (start + end) / 2);
                forkJoinTask1.fork();
                TestForkJoinTask forkJoinTask2 = new TestForkJoinTask((start+end) / 2 + 1, end);
                forkJoinTask2.fork();
                return forkJoinTask1.join() + forkJoinTask2.join();
            }
        }

    }



}
